﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using UniCT.LinkShareWpf.Interface;
using LinkShareWpf.Commands;
using System.Windows.Controls;
using UniCT.LinkShareWpf.CommunicationChannel;
using System.Collections.ObjectModel;
using System.Windows.Data;
using LinkShareWpf.Properties;
using System.Windows;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Drawing;
using System.Windows.Media.Imaging;
using UniCT.LinkShareWpf.Model;

namespace LinkShareWpf.ViewModel
{
    // Una cosa importante da notare nella creazione di questo ViewModel è stata la creazione tramite codice
    // del datagrid e quindi la possibilità di definire l'evento doppio click e l'implementazione qui dentro
    // a differenza di quanto è successo nel ViewModel del "LocalResourcesControl"

    public partial class NetworkResourceViewModel
    {

        #region Commmands
        public DelegateCommand FilterCommand { get; private set; }
        public DelegateCommand TypeOfResourceCheckedCommand { get; private set; }
        public DelegateCommand RatingOfResourceCheckedCommand { get; private set; }
        public DelegateCommand CloseXCommand { get; private set; }
        public DelegateCommand ResetCommand { get; private set; }
        #endregion

        #region Private
        private Dictionary<Guid, ObservableCollection<Resource>> myResourcesCollection;
        private NetFilter netFilter;
        private TabControl tc1;
        private ObservableCollection<Resource> tempC;
        #endregion

        #region Properties
        public NetFilter NetFilter
        {
            get { return netFilter; }
            set { netFilter = value; }
        }
        public ObservableCollection<Resource> TempC
        {
            get { return tempC; }
            set { tempC = value; }
        }
        #endregion

       
        // Colleghiamo gli id dei netfilter(ovvero delle ricerche)
        // ad una lista di risultati che sono quelli che riceviamo
       

        public NetworkResourceViewModel()
        {
            FilterCommand = new DelegateCommand(commandParameter => FilterFunction(commandParameter));
            MyTempResourcesList.Instance.addNewResource += NewNetResourceEventHandler;
            myResourcesCollection = new Dictionary<Guid, ObservableCollection<Resource>>();
            netFilter = new NetFilter();
            netFilter.Type = "allRButton";
            netFilter.Rating = "allRatRButton";
           
            TypeOfResourceCheckedCommand = new DelegateCommand(o => TypeOfResource(o));
            RatingOfResourceCheckedCommand = new DelegateCommand(o => RatingOfResource(o));
            CloseXCommand = new DelegateCommand(o => CloseTab_Execute(o), o => CloseTab_CanExecute(o));
            ResetCommand = new DelegateCommand(commandParameter => ResetFunction());
        }

        private void CloseTab_Execute(object param)
        {
            TabItem ti = param as TabItem;
            string netfilterId = ti.Name.Remove(0, 2);
            myResourcesCollection.Remove(Guid.Parse(netfilterId));
            if (ti != null)
                tc1.Items.Remove(param);
        }

        private bool CloseTab_CanExecute(object param)
        {
            if (tc1.Items.Count > 1)
                return true;
            else
                return false;
        }

        private void RatingOfResource(object nameOfRadioButton)
        {
            Console.WriteLine(nameOfRadioButton.ToString());
            netFilter.Rating = nameOfRadioButton.ToString();
        }

        private void TypeOfResource(object nameOfRadioButton)
        {
            Console.WriteLine(nameOfRadioButton.ToString());
            netFilter.Type = nameOfRadioButton.ToString();
        }
        
        private void ResetFunction()
        {
            WindowHandler.Instance.ReloadUserControl("NetworkUserControl");
        }

        private void NewNetResourceEventHandler(object sender, EventArgs e)
        {
            NetResource netRes = MyTempResourcesList.Instance.ElementAt<NetResource>(0);
            Console.WriteLine("Ho ricevuto una risorsa relativa al netFilter:" + netRes.Id);

            //Recupero l'Id del NetFilter, che corrisponde alla ricerca
            string name = netRes.Id.ToString();
           
            // La TabControl potrebbe essere stata resettata
            if (tc1 != null)
            {
                // Se la TabItem è stata chiusa devo ignorare la ricezione della risorsa
                // La tab è stata chiusa se il TabControl non contiene più una tab con quell'Id
                foreach (TabItem tabItem in tc1.Items)
                {
                    // Se entro nell'if, la tab è aperta ed interessa aggiornare la vista
                    if (tabItem.Name.Equals("id"+name.Replace("-","")))
                    {
                        #region aggiornamentoVista
                        if (!containsResource(netRes))
                        {
                            myResourcesCollection[netRes.Id].Add(netRes as Resource);
                            // Oltre ad aggiungere la risorsa alla lista 
                            // devo recuperare l'immagine e salvarla nel filesystem
                            try
                            {
                                String photolocation = Settings.Default.CoversPath + "\\Temp\\" + System.IO.Path.GetFileName(netRes.CInfo.CoverName);
                                File.WriteAllBytes(photolocation, netRes.ImageBuffer);
                            }
                            catch (Exception ee)
                            {
                                Console.WriteLine("NeteorkResourceVM: " + ee.Message);
                            }

                        }
                        #endregion
                        DataGrid dg = tabItem.Content as DataGrid;
                        dg.ItemsSource = myResourcesCollection[netRes.Id];
                    }
                }
            }
         
            // Aggiunta di un eventuale nodo a bassa priorità
            #region EventualeAggiuntaNodo
            Node node = new Node();
            node.Url = netRes.Sender.ToString();
            Console.WriteLine("NetworkResourceViewModel, provo ad aggiungere: "+ node.Url);
            ConnectionHandler.Instance.AddNode(node, false);
            #endregion
        }

        //Controllo tramite il campo URL (univoco per distinguere la singola risorsa)
        //Se ho gia ricevuto quella risorsa
        private bool containsResource(NetResource netResource)
        {
            try
            {
                // Se sono in questa parte di codice proprio quando chiudo una tab e quindi cancello 
                // l'ObsColl dal dizionario si solleva un'eccez.
                ObservableCollection<Resource> myObList = myResourcesCollection[netResource.Id];
                string url = netResource.Url;
                foreach (Resource res in myObList)
                {
                    //URL è UNIVOCO PER QUALSIASI RISORSA. SE COMBACIA STIAMO VALUTANDO LA STESSA RISORSA
                    //NON POSSONO ESISTERE 2 RISORSE DIVERSE CON URL UGUALI
                    if (res.Url.Equals(url))
                        return true;
                }
                return false;
            }
            catch
            {
                return true;
            }
        }

        private void FilterFunction(object commandParameter)
        {
            // Nuovo id da assegnare al NetFilter, per la nuova ricerca
            netFilter.Id = Guid.NewGuid();

            ObservableCollection<Resource> myResources = new ObservableCollection<Resource>();
            // Nuova coppia: NetFilter <-> ListaDiRisorseRicevute
            myResourcesCollection.Add(netFilter.Id, myResources);

            tc1 = commandParameter as TabControl;
          
            TabItem ti = new TabItem();
            ti.Content =createDataGrid();
           
            // Il Name di un UI Control non può cominciare con una cifra e/o contenere caratteri strani
            string name = netFilter.Id.ToString().Replace("-", "");
            ti.Name = "id"+name;

            tc1.Items.Add(ti);
            tc1.Items.Refresh();
            tc1.SelectedItem = ti; 

            if (netFilter.Title != String.Empty)
                ti.Header = netFilter.Title;
            else
                ti.Header = "Ricerca...";

             UInt32 x;
             if (!UInt32.TryParse(netFilter.SeasonN, out x))
                     netFilter.SeasonN = "All";
             if (!UInt32.TryParse(netFilter.EpisodeN, out x))
                     netFilter.EpisodeN = "All";

             Console.WriteLine("Inoltro filtro con id: " + netFilter.Id);
             ConnectionHandler.Instance.SearchResources(netFilter);
        }

        private DataGrid createDataGrid()
        {
            DataGrid dg = new DataGrid();
            dg.AutoGenerateColumns = false;
            dg.IsReadOnly = true;
            
            DataGridTextColumn titleColumn = new DataGridTextColumn();
            titleColumn.Header = "Titolo";
            Binding b = new Binding("CInfo.Title");
            b.Mode = BindingMode.OneWay;
            titleColumn.Binding = b;
            dg.Columns.Add(titleColumn);

            DataGridTextColumn seasonColumn = new DataGridTextColumn();
            seasonColumn.Header = "Stagione";
            b = new Binding("CInfo.SeasonNumber");
            b.Mode = BindingMode.OneWay;
            seasonColumn.Binding = b;
            dg.Columns.Add(seasonColumn);

            DataGridTextColumn episodColumn = new DataGridTextColumn();
            episodColumn.Header = "Episodio";
            b = new Binding("CInfo.EpisodNumber");
            b.Mode = BindingMode.OneWay;
            episodColumn.Binding = b;
            dg.Columns.Add(episodColumn);

            //Colonna rating
            DataGridTemplateColumn ratingColumn = new DataGridTemplateColumn();
            ratingColumn.Header = "Rating";
            //Permette di realizzare l'ordinamento delle risorse anche per il valore del Rating
            //Ricorda al rating è associato un double
            ratingColumn.SortMemberPath = "Rating";
            ratingColumn.CellTemplate = App.Current.FindResource("RatingTemplate") as DataTemplate;
            dg.Columns.Add(ratingColumn);

            DataGridTextColumn languageColumn = new DataGridTextColumn();
            languageColumn.Header = "Lingua";
            b = new Binding("CInfo.Language");
            b.Mode = BindingMode.OneWay;
            languageColumn.Binding = b;
            dg.Columns.Add(languageColumn);

            DataGridTextColumn subLanguageColumn = new DataGridTextColumn();
            subLanguageColumn.Header = "SottoTitoli";
            b = new Binding("CInfo.SubTitleLanguage");
            b.Mode = BindingMode.OneWay;
            subLanguageColumn.Binding = b;
            dg.Columns.Add(subLanguageColumn);

            dg.MouseDoubleClick += DataGrid_MouseDoubleClickEventHandler;

            return dg;
        }

        private void DataGrid_MouseDoubleClickEventHandler(object sender, System.Windows.Input.MouseButtonEventArgs e)
         {
             DataGrid dg = sender as DataGrid;
             DataGridRow row = ItemsControl.ContainerFromElement(dg, e.OriginalSource as DependencyObject) as DataGridRow;
             if (row != null)
                 WindowHandler.Instance.ShowWindow(dg.ItemsSource as ObservableCollection<Resource>, dg.CurrentItem as Resource, GetType());
         }
    
    }

}
